/*
 * @Author: ColdV
 * @Date: 2021-08-04 23:09:43
 * @LastEditTime: 2021-08-06 15:34:05
 * @LastEditors: ColdV
 * @Description: 
 * @FilePath: /chaos_alpha/src/common/thread/Thread.h
 * 
 */
#pragma once

#include "stdafx.h"
#include "common.h"

#ifdef _WIN32
#define THREAD_FUNCTION_PRE unsigned int __stdcall
#else
#define THREAD_FUNCTION_PRE void*
#endif // _WIN32


#ifdef _WIN32
typedef unsigned int (__stdcall *PThreadFunc)(void*);
#else
typedef	void* (*PThreadFunc)(void*);
#endif // _WIN32


#ifdef _WIN32
#define THREAD_LOCAL	__declspec(thread)
#else
#define THREAD_LOCAL	__thread
#endif // _WIN32

namespace chaos
{
	extern THREAD_LOCAL thread_t t_curThreadId;
	typedef std::function<void()> ThreadFunc;
	
	class Thread : public NonCopyable
	{
	public:
		explicit Thread(const ThreadFunc& func, const std::string& name = "");
		~Thread();

		int Start();

		int Join();

		thread_t GetTid() const { return m_tid; }

		static inline thread_t CurrentTid()
		{
			if (t_curThreadId == 0)
				t_curThreadId = ::GetTid();
			return t_curThreadId;
		}

#ifdef _WIN32
		HANDLE GetThread() const { return m_hThread; }
#endif

	private:
		static THREAD_FUNCTION_PRE Work(void*);

	private:
		thread_t m_tid;
		std::string m_name;
		ThreadFunc m_func;
		bool m_started;
		bool m_joined;

#ifdef _WIN32
		HANDLE m_hThread;
#endif // _WIN32

	};
}	// namespace chaos
